package com.example.sources.handler;

import com.example.custom.mybatis.entity.Userinfo;
import com.example.sources.Insert;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author liyuncong
 * @version 1.0
 * @file InsertHandler
 * @brief InsertHandler
 * @details InsertHandler
 * @date 2022-11-14
 *
 * Edit History
 * ----------------------------------------------------------------------------
 * DATE                        NAME               DESCRIPTION
 * 2022-11-14                  liyuncong          Created
 */
public class InsertHandler extends AbstractHandlerBase {
    @Override
    public String parseSql(Method method) {
        final Insert annotation = method.getAnnotation(Insert.class);
        if (null != annotation) {
            return annotation.value();
        }
        return null;
    }

    @Override
    public Object process(
        Method method, Object[] args, String oldSql, Connection connection
    ) throws Exception {
        final Map<String, Object> paramValueMappingMap =
            paramValueMappingMap(method.getParameters(), args);

        final Map<String, Object> sqlMap = parseSql(oldSql);

        final String newSql = (String) sqlMap.get("sql");
        final List<String> paramsIndex = (List<String>) sqlMap.get("params");

        final PreparedStatement statement = connection.prepareStatement(newSql);
        processSql(statement, paramValueMappingMap, paramsIndex);

        final int result = statement.executeUpdate();
        statement.close();
        connection.close();
        return result;
    }

    protected static Map<String, Object> paramValueMappingMap(
        Parameter[] parameters, Object[] values
    ) {
        Userinfo userinfo = (Userinfo) values[0];
        Field[] allFields = userinfo.getClass().getDeclaredFields();
        Map<String, Object> userMap = new HashMap<>();
        for (Field field : allFields) {
            field.setAccessible(true);
            Object value = null;
            try {
                value = field.get(userinfo);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            userMap.put(field.getName(), value);
        }
        return userMap;
    }
}
